﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using System.Security.Cryptography;

namespace PetaFrame.Security
{
    /// <summary>
    /// MD5 ,SHA1,SHA256,SHA384,SHA512,RIJNDEAL,AES,RSA Algoritmalarını Kullanarak Verilen string Değerleri Şifreler veya Çözer
    /// </summary>
    public static class Crytography
    {
        public enum HashType : int
        {
            SHA256,
            SHA384,
            SHA512,
            RIJNDAEL,
            SHA1,
            MD5,
            AES
        }

        //private const string teststring="Gumruk Web Portal";
        private const string teststring = "kullanılandeger";
        #region AES

        static byte[] DecryptAes(byte[] cipherData,
                                 byte[] Key, byte[] IV)
        {

            MemoryStream ms = new MemoryStream();

            Aes alg = Aes.Create();

            alg.Key = Key;
            alg.IV = IV;


            CryptoStream cs = new CryptoStream(ms,
                alg.CreateDecryptor(), CryptoStreamMode.Write);


            cs.Write(cipherData, 0, cipherData.Length);


            cs.Close();

            byte[] decryptedData = ms.ToArray();

            return decryptedData;
        }

        static string DecryptAes(string cipherText)
        {

            byte[] cipherBytes = Convert.FromBase64String(cipherText);


            PasswordDeriveBytes pdb = new PasswordDeriveBytes(teststring,
                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 
            0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

            byte[] decryptedData = DecryptAes(cipherBytes,
                pdb.GetBytes(32), pdb.GetBytes(16));


            return System.Text.Encoding.Unicode.GetString(decryptedData);
        }
        static string DecryptAes(byte[] cipherBytes)
        {
            PasswordDeriveBytes pdb = new PasswordDeriveBytes(teststring,
                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 
            0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

            byte[] decryptedData = DecryptAes(cipherBytes,
                pdb.GetBytes(32), pdb.GetBytes(16));


            return System.Text.Encoding.Unicode.GetString(decryptedData);
        }
        private static string GETAES(string clearText)
        {
            byte[] clearBytes =
              System.Text.Encoding.Unicode.GetBytes(clearText);

            PasswordDeriveBytes pdb = new PasswordDeriveBytes(teststring,
                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
            0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});


            byte[] encryptedData = GETAESTOBYTE(clearBytes,
                     pdb.GetBytes(32), pdb.GetBytes(16));

            return Convert.ToBase64String(encryptedData);

        }
        private static byte[] GETAESTOBYTE(string clearText)
        {
            byte[] clearBytes =
              System.Text.Encoding.Unicode.GetBytes(clearText);

            PasswordDeriveBytes pdb = new PasswordDeriveBytes(teststring,
                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
            0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});


            byte[] encryptedData = GETAESTOBYTE(clearBytes,
                     pdb.GetBytes(32), pdb.GetBytes(16));

            return encryptedData;

        }
        static byte[] GETAESTOBYTE(byte[] clearData, byte[] Key, byte[] IV)
        {

            MemoryStream ms = new MemoryStream();


            Aes alg = Aes.Create();


            alg.Key = Key;
            alg.IV = IV;


            CryptoStream cs = new CryptoStream(ms,
               alg.CreateEncryptor(), CryptoStreamMode.Write);


            cs.Write(clearData, 0, clearData.Length);


            cs.Close();


            byte[] encryptedData = ms.ToArray();

            return encryptedData;
        }

        #endregion

        #region SHA2
        private static string GETSHA256(string clearText)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] HashValue;
            byte[] message = encoding.GetBytes(clearText);
            SHA256Managed hasher = new SHA256Managed();
            string hex = "";
            HashValue = hasher.ComputeHash(message);
            foreach (byte x in HashValue)
            {
                hex += string.Format("{0:x2}", x);
            }
            return hex;

        }
        private static byte[] GETSHA256TOBYTE(string clearText)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] message = encoding.GetBytes(clearText);
            SHA256Managed hasher = new SHA256Managed();
            return hasher.ComputeHash(message);
        }
        private static string GETSHA384(string clearText)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] HashValue;
            byte[] message = encoding.GetBytes(clearText);
            SHA384Managed hasher = new SHA384Managed();
            string hex = "";
            HashValue = hasher.ComputeHash(message);
            foreach (byte x in HashValue)
            {
                hex += string.Format("{0:x2}", x);
            }
            return hex;

        }
        private static byte[] GETSHA384TOBYTE(string clearText)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] message = encoding.GetBytes(clearText);
            SHA384Managed hasher = new SHA384Managed();
            return hasher.ComputeHash(message);
        }
        private static string GETSHA512(string clearText)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] HashValue;
            byte[] message = encoding.GetBytes(clearText);
            SHA512Managed hasher = new SHA512Managed();
            string hex = "";
            HashValue = hasher.ComputeHash(message);
            foreach (byte x in HashValue)
            {
                hex += string.Format("{0:x2}", x);
            }
            return hex;

        }
        private static byte[] GETSHA512TOBYTE(string clearText)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] message = encoding.GetBytes(clearText);
            SHA512Managed hasher = new SHA512Managed();
            return hasher.ComputeHash(message);

        }
        #endregion

        #region MD5
        private static string GETMD5(string ClearText)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] HashValue;
            byte[] message = encoding.GetBytes(ClearText);
            MD5 hasher = new MD5CryptoServiceProvider();
            string hex = "";
            HashValue = hasher.ComputeHash(message);
            foreach (byte x in HashValue)
            {
                hex += string.Format("{0:x2}", x);
            }
            return hex;
        }
        private static byte[] GETMD5TOBYTE(string ClearText)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] message = encoding.GetBytes(ClearText);
            MD5 hasher = new MD5CryptoServiceProvider();
            return hasher.ComputeHash(message);
        }
        #endregion

        #region SHA1
        private static string GETSHA1(string clearText)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] HashValue;
            byte[] message = encoding.GetBytes(clearText);
            SHA1Managed hasher = new SHA1Managed();
            string hex = "";
            HashValue = hasher.ComputeHash(message);
            foreach (byte x in HashValue)
            {
                hex += string.Format("{0:x2}", x);
            }
            return hex;
        }
        private static byte[] GETSHA1TOBYTE(string clearText)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] message = encoding.GetBytes(clearText);
            SHA1Managed hasher = new SHA1Managed();
            return hasher.ComputeHash(message);

        }
        #endregion

        #region RIJNDEAL
        private static byte[] GETRIJNDAELTOBYTE(string clearText)
        {

            byte[] clearBytes =
              System.Text.Encoding.Unicode.GetBytes(clearText);

            PasswordDeriveBytes pdb = new PasswordDeriveBytes(teststring,
                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
            0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});


            byte[] encryptedData = GETRIJNDEALTOBYTE(clearBytes,
                     pdb.GetBytes(32), pdb.GetBytes(16));

            return encryptedData;

        }
        private static string GETRIJNDAEL(string clearText)
        {

            byte[] clearBytes =
              System.Text.Encoding.Unicode.GetBytes(clearText);

            PasswordDeriveBytes pdb = new PasswordDeriveBytes(teststring,
                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 
            0x65, 0x64, 0x76, 0x65, 0x64, 0x65, 0x76});


            byte[] encryptedData = GETRIJNDEALTOBYTE(clearBytes,
                     pdb.GetBytes(32), pdb.GetBytes(16));

            return Convert.ToBase64String(encryptedData);

        }
        static byte[] GETRIJNDEALTOBYTE(byte[] clearData, byte[] Key, byte[] IV)
        {

            MemoryStream ms = new MemoryStream();


            Rijndael alg = Rijndael.Create();


            alg.Key = Key;
            alg.IV = IV;


            CryptoStream cs = new CryptoStream(ms,
               alg.CreateEncryptor(), CryptoStreamMode.Write);


            cs.Write(clearData, 0, clearData.Length);


            cs.Close();


            byte[] encryptedData = ms.ToArray();

            return encryptedData;
        }
        static string DecryptRijndeal(string cipherText)
        {

            byte[] cipherBytes = Convert.FromBase64String(cipherText);


            PasswordDeriveBytes pdb = new PasswordDeriveBytes(teststring,
                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 
            0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

            byte[] decryptedData = DecryptRijndeal(cipherBytes,
                pdb.GetBytes(32), pdb.GetBytes(16));


            return System.Text.Encoding.Unicode.GetString(decryptedData);
        }
        static string DecryptRijndeal(byte[] cipherBytes)
        {
            PasswordDeriveBytes pdb = new PasswordDeriveBytes(teststring,
                new byte[] {0x49, 0x76, 0x61, 0x6e, 0x20, 0x4d, 0x65, 
            0x64, 0x76, 0x65, 0x64, 0x65, 0x76});

            byte[] decryptedData = DecryptRijndeal(cipherBytes,
                pdb.GetBytes(32), pdb.GetBytes(16));


            return System.Text.Encoding.Unicode.GetString(decryptedData);
        }
        static byte[] DecryptRijndeal(byte[] cipherData, byte[] Key, byte[] IV)
        {

            MemoryStream ms = new MemoryStream();

            Rijndael alg = Rijndael.Create();

            alg.Key = Key;
            alg.IV = IV;


            CryptoStream cs = new CryptoStream(ms,
                alg.CreateDecryptor(), CryptoStreamMode.Write);


            cs.Write(cipherData, 0, cipherData.Length);


            cs.Close();

            byte[] decryptedData = ms.ToArray();

            return decryptedData;
        }
        #endregion

        #region Encrypt

        /// <summary>
        ///  Verilen string Değeri Şifreler
        /// </summary>
        /// <param name="clearText">Şifrelenecek Veri</param>
        /// <param name="type"></param>
        /// <returns>Şifrelenmiş Veriyi string Tipinde Döner</returns>
        public static string Encrypt(string clearText, HashType type)
        {
            string encryptdata = "";
            switch (type)
            {
                case HashType.SHA256:
                    encryptdata = GETSHA256(clearText);
                    break;
                case HashType.SHA384:
                    encryptdata = GETSHA384(clearText);
                    break;
                case HashType.SHA512:
                    encryptdata = GETSHA512(clearText);
                    break;
                case HashType.RIJNDAEL:
                    encryptdata = GETRIJNDAEL(clearText);
                    break;
                case HashType.SHA1:
                    encryptdata = GETSHA1(clearText);
                    break;
                case HashType.MD5:
                    encryptdata = GETMD5(clearText);
                    break;
                case HashType.AES:
                    encryptdata = GETAES(clearText);
                    break;
                
            }
            return encryptdata;
        }

        /// <summary>
        ///  Verilen string Değeri Şifreler
        /// </summary>
        /// <param name="clearText">Şifrelenecek Veri</param>
        /// <param name="type"></param>
        /// <returns>Şifrelenmiş Veriyi byte[] Tipinde Döner</returns>
        public static byte[] EncryptToByte(string clearText, HashType type)
        {
            byte[] encryptdata = null;
            switch (type)
            {
                case HashType.SHA256:
                    encryptdata = GETSHA256TOBYTE(clearText);
                    break;
                case HashType.SHA384:
                    encryptdata = GETSHA384TOBYTE(clearText);
                    break;
                case HashType.SHA512:
                    encryptdata = GETSHA512TOBYTE(clearText);
                    break;
                case HashType.RIJNDAEL:
                    encryptdata = GETRIJNDAELTOBYTE(clearText);
                    break;
                case HashType.SHA1:
                    encryptdata = GETSHA1TOBYTE(clearText);
                    break;
                case HashType.MD5:
                    encryptdata = GETMD5TOBYTE(clearText);
                    break;
                case HashType.AES:
                    encryptdata = GETAESTOBYTE(clearText);
                    break;
             
            }
            return encryptdata;
        }

        /// <summary>
        /// Verilen string Değeri Şifreler
        /// </summary>
        /// <param name="clearText">Şifrelenecek Veri</param>
        /// <param name="keyinfo">RSA PArametre</param>
        /// <returns>Şifrelenmiş Veriyi string Tipinde Döner</returns>
        public static string Encrypt(string clearText, RSAParameters keyinfo)
        {
            return System.Text.Encoding.Unicode.GetString(EncryptToByte(clearText, keyinfo));
        }

        /// <summary>
        ///  Verilen string Değeri Şifreler
        /// </summary>
        /// <param name="clearText">Şifrelenecek Veri</param>
        /// <param name="keyinfo">RSA PArametre</param>
        /// <returns>Şifrelenmiş Veriyi byte[] Tipinde Döner</returns>
        public static byte[] EncryptToByte(string clearText, RSAParameters keyinfo)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] plaindata = encoding.GetBytes(clearText);
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
            RSA.ImportParameters(keyinfo);
            return RSA.Encrypt(plaindata, false);
        }

        #endregion

        #region Decrypt
        /// <summary>
        /// Verilen Şifrelenmiş string Değerin Şifresini Çözer. Bu Method Sadece Rijndeal ve Aes viçin Kullanılır.
        /// </summary>
        /// <param name="chipperText">Şifrelenmiş string Veri</param>
        /// <param name="type">Şifresi Çözülmüş Veri</param>
        /// <returns>Şifresi Çözülmüş Veriyi string Tipinde Döner.</returns>
        public static string Decrypt(string chipperText, HashType type)
        {
            string clearText = "";
            switch (type)
            {
                case HashType.RIJNDAEL:
                    clearText = DecryptRijndeal(chipperText);
                    break;
                case HashType.AES:
                    clearText = DecryptAes(chipperText);

                    break;

            }
            return clearText;
        }

        /// <summary>
        /// Verilen Şifrelenmiş byte[] Değerin Şifresini Çözer. Bu Method Sadece Rijndeal ve Aes  için Kullanılır.
        /// </summary>
        /// <param name="chipperByte">Şifrelenmiş byte[] Veri</param>
        /// <param name="type">Şifresi Çözülmüş Veri</param>
        /// <returns>Şifresi Çözülmüş Veriyi string Tipinde Döner.</returns>
        public static string Decrypt(byte[] chipperByte, HashType type)
        {
            string clearText = null;
            switch (type)
            {
                case HashType.RIJNDAEL:
                    clearText = DecryptRijndeal(chipperByte);
                    break;
                case HashType.AES:
                    clearText = DecryptAes(chipperByte);

                    break;

            }
            return clearText;
        }

        /// <summary>
        /// Verilen Şifrelenmiş string Değerin Şifresini Çözer. Bu Method Sadece RSA için Kullanılır.
        /// </summary>
        /// <param name="chipperText">Şifrelenmiş string Veri</param>
        /// <param name="keyinfo">RSA parametre</param>
        /// <returns>Şifresi Çözülmüş Değeri string Tipinde Döner.</returns>
        public static string Decrypt(string chipperText, RSAParameters keyinfo)
        {
            UnicodeEncoding encoding = new UnicodeEncoding();
            byte[] plaindata = encoding.GetBytes(chipperText);
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
            RSA.ImportParameters(keyinfo);
            return System.Text.Encoding.Unicode.GetString(RSA.Decrypt(plaindata, false));
        }

        /// <summary>
        ///  Verilen Şifrelenmiş string Değerin Şifresini Çözer. Bu Method Sadece RSA için Kullanılır.
        /// </summary>
        /// <param name="chipperByte">Şifrelenmiş byte[] Veri</param>
        /// <param name="keyinfo">RSA parametre</param>
        /// <returns>Şifresi Çözülmüş Değeri string Tipinde Döner.</returns>
        public static string Decrypt(byte[] chipperByte, RSAParameters keyinfo)
        {
            RSACryptoServiceProvider RSA = new RSACryptoServiceProvider();
            RSA.ImportParameters(keyinfo);
            return System.Text.Encoding.Unicode.GetString(RSA.Decrypt(chipperByte, false));
        }
        #endregion

    }
}